package cn.zyb.user.service.impl;

import cn.zyb.basic.contant.VerifyCodeConstant;
import cn.zyb.basic.exception.BusinessException;
import cn.zyb.basic.service.Impl.BaseServiceImpl;
import cn.zyb.basic.util.Md5Utils;
import cn.zyb.basic.util.StrUtils;
import cn.zyb.user.domain.Logininfo;
import cn.zyb.user.domain.User;
import cn.zyb.user.dto.UserDto;
import cn.zyb.user.mapper.LogininfoMapper;
import cn.zyb.user.mapper.UserMapper;
import cn.zyb.user.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

/**
 * 业务实现类：
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

  @Autowired
  private RedisTemplate redisTemplate;
  @Autowired
  private LogininfoMapper logininfoMapper;
  @Autowired
  private UserMapper userMapper;
  @Autowired
  private JavaMailSender javaMailSender;


  @Override
  public void add(User user) {
    //处理密码和盐值
    //盐值
    String salt = StrUtils.getComplexRandomString(32);
    user.setSalt(salt);
    //密码 - 加盐加密之后的
    String md5Pwd = Md5Utils.encrypByMd5(user.getPassword() + salt);
    user.setPassword(md5Pwd);

    Logininfo logininfo = user2Logininfo(user);
    logininfoMapper.save(logininfo);

    user.setLogininfoId(logininfo.getId());
    //调用父类的方法添加数据
    super.add(user);
  }

  @Override
  public void del(Long id) {
    //根据id查询整个对象 - 为了获取对象的logininfo_id
    User user = userMapper.loadById(id);
    //删除user对象
    super.del(id);
    logininfoMapper.remove(user.getLogininfoId());
  }

  @Override
  public void update(User user) {//参数user来自于前端，是没有logininfo_id的
    //处理密码和盐值
    //盐值
    String salt = StrUtils.getComplexRandomString(32);
    user.setSalt(salt);
    //密码 - 加盐加密之后的
    String md5Pwd = Md5Utils.encrypByMd5(user.getPassword() + salt);
    user.setPassword(md5Pwd);


    //根据id查询整个对象 - 为了获取对象的logininfo_id
    User oldUser = userMapper.loadById(user.getId());
    //更新user
    super.update(user);
    //查询以前的Logininfo对象
    Logininfo oldLogininfo = logininfoMapper.loadById(oldUser.getLogininfoId());

    //将新的数据拷贝到oldLogininfo对象中：type，disable都是以前的
    BeanUtils.copyProperties(user,oldLogininfo);
    //更新
    logininfoMapper.update(oldLogininfo);
  }
  //邮箱注册
  @Override
  public void registerEmail(UserDto userDto) throws MessagingException {
    String email = userDto.getEmail();
    String password = userDto.getPassword();
    String passwordRepeat = userDto.getPasswordRepeat();
    //1.1校验空值
    if(StringUtils.isEmpty(email) || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordRepeat)){
      throw new BusinessException("数据不能为空哦");
    }
        /*//1.2判断两次输入的密码是否一致 (在前段判断了这可以不判断)
        if(!password.equals(passwordRepeat)){
            throw new BusinessException("两次密码不一致");
        }*/

    //1.2校验邮箱是否被注册过
    User user = userMapper.loadByEmail(email);
    if (user != null){
      throw new BusinessException("当前邮箱已被注册");
    }

    //2.发送邮件:注册
    //创建复杂邮件对象
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    //发送复杂邮件的工具类‘
    MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"UTF-8");
    //设置发送方
    helper.setFrom("1757295077@qq.com");
    //主题
    helper.setSubject("宠物乐园");
    //设置内容
    helper.setText("<h1>宠物乐园</h1>"
      + "<a href='http://localhost:8080/user/register/Successfully/'>点击链接完成邮箱注册</a>",true);
    //设置收件人
    helper.setTo(userDto.getEmail());
    //发送
    javaMailSender.send(mimeMessage);


    //2.保存数据(验证码都正确)把userDto对象的数据保存到user
    User newUser = userDto2User(userDto);
    //调用方法把userDto的值给logininfo
    Logininfo logininfo = user2Logininfo(newUser);

    //保存到logininfo后获取自增主键
    logininfoMapper.save(logininfo);
    //2.2在保存t_user
    user.setLogininfoId(logininfo.getId());
    //保存
    userMapper.save(user);
  }
  @Override
  public void phoneRegister(UserDto userDto) {
    String phone = userDto.getPhone();
    String code = userDto.getCode();
    String password = userDto.getPassword();
    String passwordRepeat = userDto.getPasswordRepeat();
    //1.校验
    //1.1.空值校验
    if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)
      || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordRepeat)){
      throw new BusinessException("数据不能为空!!!");
    }
    //1.2.校验密码
    if(!password.equals(passwordRepeat)){
      throw new BusinessException("两次密码不一致!!!");
    }
    //1.3.校验手机验证码 - 是否过期，是否正确  【regisrer:1565566666 112355:154545454555】
    Object obj = redisTemplate.opsForValue().get(VerifyCodeConstant.REGISTER_CODE_PREFIX + phone);
    if(obj == null){
      throw new BusinessException("验证码过期!!!");
    }
    if(!obj.toString().split(":")[0].equals(code)){
      throw new BusinessException("验证码错误!!!");
    }

    //2.保存数据
    User user = userDto2User(userDto);
    Logininfo logininfo = user2Logininfo(user);
    //2.1.保存t_logininfo对象 - 获取自增id - 设置到user
    logininfoMapper.save(logininfo);
    //2.2.保存t_user对象
    user.setLogininfoId(logininfo.getId());
    userMapper.save(user);
  }

  //对象转对象就用这种方式
  private User userDto2User(UserDto userDto) {
    User user = new User();
    user.setUsername(userDto.getPhone());
    user.setPhone(userDto.getPhone());
    //盐值
    String salt = StrUtils.getComplexRandomString(32);
    user.setSalt(salt);
    //密码 - 加盐加密之后的
    String md5Pwd = Md5Utils.encrypByMd5(userDto.getPassword() + salt);
    user.setPassword(md5Pwd);
    user.setState(1);
    return user;
  }

  private Logininfo user2Logininfo(User user) {
    Logininfo logininfo = new Logininfo();
    //按照属性同名原则进行拷贝
    BeanUtils.copyProperties(user,logininfo);
    logininfo.setType(1);//1-表示用户
    return logininfo;
  }
}
